package com.qiangshi.realTimeInformation.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangshi.common.core.domain.vo.BarChartsVO;
import com.qiangshi.common.utils.DateUtils;
import com.qiangshi.createTableLog.domain.QsCreateTableLog;
import com.qiangshi.createTableLog.service.IQsCreateTableLogService;
import com.qiangshi.realTimeInformation.domain.QsRealTimeInformation;
import com.qiangshi.realTimeInformation.domain.to.QsRealTimeInformationListTo;
import com.qiangshi.realTimeInformation.mapper.QsRealTimeInformationMapper;
import com.qiangshi.realTimeInformation.service.IQsRealTimeInformationService;
import com.qiangshi.system.mybatis.config.MybatisConfig;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * RealTimeInformationService业务层处理
 *
 * @author ccm
 * @date 2022-03-02
 */
@Service
public class QsRealTimeInformationServiceImpl extends ServiceImpl<QsRealTimeInformationMapper, QsRealTimeInformation> implements IQsRealTimeInformationService {
    @Autowired
    IQsCreateTableLogService createTableLogService;

    public static String getWeekOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return DateUtils.parseDateToStr(DateUtils.YYYY, date) + "年第" + (calendar.get(Calendar.WEEK_OF_YEAR) - 1) + "周";
    }

    /**
     * 查询RealTimeInformation列表
     *
     * @param realTimeInformationListTo
     * @return QsRealTimeInformation
     */
    @Override
    public List<QsRealTimeInformation> selectQsRealTimeInformationList(QsRealTimeInformationListTo realTimeInformationListTo) {
        List<QsRealTimeInformation> realTimeInformationList = new ArrayList<>();
        QueryWrapper<QsCreateTableLog> createTableLogQueryWrapper = new QueryWrapper<>();
        if (CollectionUtils.isNotEmpty(realTimeInformationListTo.getCaseList())) {
            createTableLogQueryWrapper.lambda().in(QsCreateTableLog::getCaseNumber, realTimeInformationListTo.getCaseList());
        }
        List<String> dateList = DateUtils.getBetweenMonth(realTimeInformationListTo.getStartTime(), realTimeInformationListTo.getEndTime());
        createTableLogQueryWrapper.lambda().or().in(QsCreateTableLog::getMonthNumber, dateList);
        List<QsCreateTableLog> createTableLogList = createTableLogService.list(createTableLogQueryWrapper);
        for (QsCreateTableLog qsCreateTableLog : createTableLogList) {
            String tableName = qsCreateTableLog.getTableName() + qsCreateTableLog.getNameSuffix();
            MybatisConfig.TABLE_NAME.set(tableName);
            QueryWrapper<QsRealTimeInformation> queryWrapper = new QueryWrapper();
            queryWrapper.lambda().between(QsRealTimeInformation::getCreateTime, realTimeInformationListTo.getStartTime(), realTimeInformationListTo.getEndTime());
            List<QsRealTimeInformation> list = list(queryWrapper);
            list.forEach(x -> x.setCaseNumber(qsCreateTableLog.getCaseNumber()));
            realTimeInformationList.addAll(list);
        }
        MybatisConfig.TABLE_NAME.set(null);
//        buildBarChartsVOList(realTimeInformationListTo, realTimeInformationList);
        return realTimeInformationList;

    }

    /**
     * 生态统计柱状图
     *
     * @param realTimeInformationListTo
     * @param realTimeInformationList
     * @return
     */
    @Override
    public List<BarChartsVO> buildBarChartsVOList(QsRealTimeInformationListTo realTimeInformationListTo, List<QsRealTimeInformation> realTimeInformationList) {
        List<BarChartsVO> barChartsVOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(realTimeInformationList)) {
            return barChartsVOList;
        }
        List<String> dateList = DateUtils.getWeekList(realTimeInformationListTo.getStartTime());
//        realTimeInformationList = realTimeInformationList.stream().sorted(Comparator.comparing(QsRealTimeInformation::getCaseNumber)
//                .thenComparing(QsRealTimeInformation::getCreateTime)).collect(Collectors.toList());
        Map<Integer, List<QsRealTimeInformation>> qsRealTimeInformationListMap = realTimeInformationList.stream().collect(Collectors.groupingBy(QsRealTimeInformation::getCaseNumber));
        for (Integer num : qsRealTimeInformationListMap.keySet()) {
            String time = qsRealTimeInformationListMap.get(num).get(0).getCreateDate();
            List<BigDecimal> list = new ArrayList<>();
            for (String date : dateList) {
                BigDecimal sum = BigDecimal.ZERO;
                if (date.equals(time)) {
                    for (QsRealTimeInformation realTimeInformation : qsRealTimeInformationListMap.get(num)) {
                        sum = sum.add(realTimeInformation.getFinishedWeight());
                    }
                }
                list.add(sum);
            }
            BarChartsVO barChartsVO = BarChartsVO.builder().name(num + "号箱 出料实际值(g)").data(list).type("bar").barWidth("60%").stack("vistors").build();
            barChartsVOList.add(barChartsVO);
        }
        return barChartsVOList;
    }

    /**
     * 周时统计
     *
     * @param realTimeInformationListTo
     * @param realTimeInformationList
     * @return
     */
    @Override
    public List<QsRealTimeInformation> selectQsRealTimeInformationListStatistics(QsRealTimeInformationListTo realTimeInformationListTo, List<QsRealTimeInformation> realTimeInformationList) {
        List<QsRealTimeInformation> resList = new ArrayList<>();
        if (CollectionUtils.isEmpty(realTimeInformationList)) {
            return resList;
        }
        Map<Integer, List<QsRealTimeInformation>> qsRealTimeInformationListMap = realTimeInformationList.stream().collect(Collectors.groupingBy(QsRealTimeInformation::getCaseNumber));
        for (Integer caseNumber : qsRealTimeInformationListMap.keySet()) {
            BigDecimal finishedWeightSum = BigDecimal.ZERO;
            Integer feedBoxNumSum = 0;
            Integer wormBoxNumSum = 0;
            Integer finishedBoxNumSum = 0;
            for (QsRealTimeInformation realTimeInformation : qsRealTimeInformationListMap.get(caseNumber)) {
                finishedWeightSum = finishedWeightSum.add(NumberUtil.toBigDecimal(realTimeInformation.getFinishedWeight()));
                feedBoxNumSum = feedBoxNumSum + NumberUtil.toBigDecimal(realTimeInformation.getFeedBoxNum()).intValue();
                wormBoxNumSum = wormBoxNumSum + NumberUtil.toBigDecimal(realTimeInformation.getWormBoxNum()).intValue();
                finishedBoxNumSum = finishedBoxNumSum + NumberUtil.toBigDecimal(realTimeInformation.getFinishedBoxNum()).intValue();
            }
            QsRealTimeInformation res = QsRealTimeInformation.builder().caseNumber(caseNumber).weekOfYear(getWeekOfYear(realTimeInformationListTo.getStartTime())).finishedWeight(finishedWeightSum).feedBoxNum(feedBoxNumSum).wormBoxNum(wormBoxNumSum).finishedBoxNum(finishedBoxNumSum).build();
            resList.add(res);
        }
        return resList;
    }

    /**
     * 分表处理
     *
     * @param tableNameList
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void handleRealTimeInformation(List<String> tableNameList) {
        for (String tableName : tableNameList) {
            MybatisConfig.TABLE_NAME.set(tableName.substring(0, tableName.lastIndexOf("_")));
            QueryWrapper<QsRealTimeInformation> queryWrapper = new QueryWrapper();
            queryWrapper.lambda().between(QsRealTimeInformation::getCreateTime,
                    DateUtils.getLastMonthBegin(), DateUtils.getLastMonthEnd());
            List<QsRealTimeInformation> realTimeInformationList = list(queryWrapper);
            removeByIds(realTimeInformationList.stream().map(QsRealTimeInformation::getId).collect(Collectors.toList()));
            MybatisConfig.TABLE_NAME.set(tableName);
            saveBatch(realTimeInformationList);
            MybatisConfig.TABLE_NAME.set(null);
        }
    }

    /**
     * 创建新表
     *
     * @param tableName
     * @return
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    @Override
    public Boolean createNewTable(String tableName,String remark) {
        baseMapper.dropTable(tableName);
        return baseMapper.createNewTable(tableName,remark) >= 1;
    }

    /**
     * 创建多个新表
     *
     * @param tableNameList
     * @return
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    @Override
    public Boolean createNewTable(List<String> tableNameList) {
        int i = 0;
        for (String tableName : tableNameList) {
            baseMapper.dropTable(tableName);
            baseMapper.createNewTable(tableName,i+1+"号生态养殖箱实时数据(附表)");
            i++;
        }
        return i >= tableNameList.size();
    }

}
